package cn.ai.http;

import cn.ai.IRAGService;
import cn.ai.response.Response;
import cn.ai.utils.JavaMethodParser;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.http.fileupload.FileUtils;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
import org.redisson.api.RList;
import org.redisson.api.RedissonClient;
import org.springframework.ai.document.Document;
import org.springframework.ai.reader.tika.TikaDocumentReader;
import org.springframework.ai.transformer.splitter.TokenTextSplitter;
import org.springframework.ai.vectorstore.PgVectorStore;
import org.springframework.core.io.PathResource;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.List;

@Slf4j
@RestController
@CrossOrigin("*")
@RequestMapping("/api/v1/rag/")
public class RAGController implements IRAGService {
    @Resource
    private RedissonClient redissonClient;
    @Resource
    private TokenTextSplitter tokenTextSplitter;
    @Resource
    private PgVectorStore pgVectorStore;
    @Resource
    private JavaMethodParser javaMethodParser;
    @Override
    @RequestMapping(value = "file/upload", method = RequestMethod.POST)
    public Response<String> uploadTag(@RequestParam("ragTag") String ragTag, @RequestParam("file") List<MultipartFile> files) {
        log.info("上传开始");
        for (MultipartFile file : files) {
            // 1. 解析文件内容
            TikaDocumentReader reader = new TikaDocumentReader(file.getResource());
            List<Document> documents = reader.get();

            // 2. 文本分块处理
            List<Document> documentsSplitter = tokenTextSplitter.apply(documents);

            // 3. 添加元数据
            documents.forEach(doc -> doc.getMetadata().put("knowledge", ragTag));
            documentsSplitter.forEach(doc -> doc.getMetadata().put("knowledge", ragTag));

            // 4. 存储到向量数据库
            pgVectorStore.accept(documentsSplitter);

            // 5. 维护标签列表
            RList<String> tags = redissonClient.getList("tags");
            if (!tags.contains(ragTag)) {
                tags.add(ragTag);
            }
        }
        log.info("上传结束");
        return Response.<String>builder().code("0000").info("上传成功").build();
    }

    @RequestMapping(value = "query_rag_tag_list", method = RequestMethod.GET)
    @Override
    public Response<List<String>> queryTag() {
        RList<String> tags = redissonClient.getList("tags");
        return Response.<List<String>>builder().code("0000").info("查询成功").data(tags).build();
    }

    @RequestMapping(value = "analyze_git_repository", method = RequestMethod.POST)
    @Override
    public Response<String> analyzeGitRepository(@RequestParam String repoUrl, @RequestParam String userName, @RequestParam String token) throws Exception {
        String localPath = "/tmp/git_repository";
        String repoProjectName = extractProjectName(repoUrl);
        if(token == null || token.isEmpty()) token = "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";
        FileUtils.deleteDirectory(new File(localPath));

        Git git = Git.cloneRepository()
                .setURI(repoUrl)
                .setDirectory(new File(localPath))
                .setCredentialsProvider(new UsernamePasswordCredentialsProvider(userName, token))
                .call();

        // 使用Files.walkFileTree遍历目录
        Files.walkFileTree(Paths.get(localPath), new SimpleFileVisitor<>(){
            @Override
            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                log.info("正在遍历文件，上传知识库：{}", file);
                try{
                    TikaDocumentReader reader = new TikaDocumentReader(new PathResource(file));
                    List<Document> documents = reader.get();
                    documents.forEach(document -> document.getMetadata().put("knowledge", repoProjectName));
                    List<Document> documentsSplitterList = javaMethodParser.parseMethods(file);
                    documentsSplitterList.forEach(document -> document.getMetadata().put("knowledge", repoProjectName));
                    pgVectorStore.accept(documentsSplitterList);
                }catch (Exception e){
                    log.error("文件上传知识库失败：{}", file);
                }
                return FileVisitResult.CONTINUE;
            }

            @Override
            public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
                log.error("访问文件失败：{}", file);
                return FileVisitResult.CONTINUE;
            }
        });
        //添加知识库记录
        RList<String> tags = redissonClient.getList("tags");
        if (!tags.contains(repoProjectName)){
            tags.add(repoProjectName);
        }

        FileUtils.deleteDirectory(new File(localPath));

        git.close();
        log.info("遍历解析路径，上传完成:{}", repoUrl);
        return Response.<String>builder().code("0000").info("调用成功").build();    }

    private String extractProjectName(String repoUrl) {
        String[] parts = repoUrl.split("/");
        String projectNameWithGit = parts[parts.length - 1];
        return projectNameWithGit.replace(".git", "");
    }
}
